package com.sangmo.fts.process.storage.service;

import com.sangmo.boot.framework.common.errors.ServiceException;
import com.sangmo.boot.framework.common.errors.StandardErrors;
import com.sangmo.boot.framework.common.utils.DateUtils;
import com.sangmo.boot.framework.data.filter.PageResult;
import com.sangmo.boot.framework.data.filter.PageSearch;
import com.sangmo.boot.framework.data.filter.ValueFilter;
import com.sangmo.boot.framework.plugin.dataview.crud.service.DelegateViewService;
import com.sangmo.boot.framework.plugin.dataview.crud.service.ViewService;
import com.sangmo.fts.common.utils.RandomUtils;
import com.sangmo.fts.process.inventory.model.IfLadingBill;
import com.sangmo.fts.process.storage.model.CsfLadingBill;
import com.sangmo.fts.process.storage.model.CsfLadingBillItem;
import com.sangmo.fts.process.storage.model.CsfLoan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class CsfLadingBillService extends DelegateViewService<CsfLadingBill> {

    @Autowired
    private CsfLadingBillEntityService csfLadingBillEntityService;

    @Autowired
    private CsfLadingBillItemEntityService csfLadingBillItemEntityService;

    @Autowired
    private CsfLoanService csfLoanService;

    @Override
    protected ViewService<CsfLadingBill> getEntityService() {
        return csfLadingBillEntityService;
    }

    public PageResult<CsfLadingBillItem> listItemsByPage(Long ladingBillId, PageSearch ps) {
        ps.getFilters().add(new ValueFilter("billId", ValueFilter.OP_EQ, ladingBillId));
        return csfLadingBillItemEntityService.search(ps);
    }

    public void commit(Long ladingBillId) {
        CsfLadingBill ladingBill = this.get(ladingBillId);
        if (null == ladingBill.getBillApplyDoc()) {
            throw new ServiceException(StandardErrors.CLIENT_ERROR.getStatus(), "error.csfLadingBill.commit.permit.disabled");
        }
        if (!CsfLadingBill.States.PENDING.equals(ladingBill.getState())) {
            throw new ServiceException(StandardErrors.CLIENT_ERROR.getStatus(), "error.csfLadingBill.commit.state.wrong");
        }
        ladingBill.setState(CsfLadingBill.States.SUBMITTED);
        this.save(ladingBill);
    }

    public void confirm(Long ladingBillId) {
        CsfLadingBill ladingBill = this.get(ladingBillId);
        if (null == ladingBill.getBillConfirmDoc()) {
            throw new ServiceException(StandardErrors.CLIENT_ERROR.getStatus(), "error.csfLadingBill.confirm.permit.disabled");
        }
        if (!CsfLadingBill.BankAckStates.PENDING.equals(ladingBill.getBankAckState())) {
            throw new ServiceException(StandardErrors.CLIENT_ERROR.getStatus(), "error.csfLadingBill.confirm.state.wrong");
        }
        ladingBill.setBankAckState(CsfLadingBill.BankAckStates.CONFIRMED);
        ladingBill.setBillCode(RandomUtils.generateRandomNum(8));
        this.save(ladingBill);
    }

    public void complete(Long ladingBillId) {
        CsfLadingBill ladingBill = this.get(ladingBillId);
        if (null == ladingBill.getBillReceiptDoc()) {
            throw new ServiceException(StandardErrors.CLIENT_ERROR.getStatus(), "error.csfLadingBill.complete.permit.disabled");
        }
        if (!CsfLadingBill.StorageAckStates.PENDING.equals(ladingBill.getStorageAckState())) {
            throw new ServiceException(StandardErrors.CLIENT_ERROR.getStatus(), "error.csfLadingBill.complete.state.wrong");
        }
        ladingBill.setStorageAckState(CsfLadingBill.StorageAckStates.COMPLETED);
        CsfLoan loan = csfLoanService.get(ladingBill.getLoanId());
        ladingBill.setPickDate(DateUtils.next(loan.getEndTime(), 1));
        this.save(ladingBill);
    }

    public PageResult<CsfLadingBill> selection(PageSearch ps) {
        ps.getFilters().add(new ValueFilter("storageAckState", ValueFilter.OP_EQ, CsfLadingBill.StorageAckStates.COMPLETED));
        return super.search(ps);
    }
}
